package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理调用处理器
 * 可以代理任意接口
 */
public class DynamicProxyHandler implements InvocationHandler {
    private final Object target; // 真实主题对象
    private final String currentUser;
    
    public DynamicProxyHandler(Object target, String currentUser) {
        this.target = target;
        this.currentUser = currentUser;
    }
    
    /**
     * 创建代理对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T createProxy(T target, String currentUser) {
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new DynamicProxyHandler(target, currentUser)
        );
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 方法执行前：权限检查
        if (!checkPermission(method.getName())) {
            throw new SecurityException("权限不足: 用户 " + currentUser + " 没有执行 " + method.getName() + " 的权限");
        }
        
        // 方法执行前：记录日志
        logBefore(method.getName(), args);
        
        // 性能监控
        long startTime = System.currentTimeMillis();
        Object result;
        try {
            // 调用真实主题的方法
            result = method.invoke(target, args);
        } catch (Exception e) {
            // 异常处理
            logException(method.getName(), e);
            throw e;
        } finally {
            // 方法执行后：性能统计
            long endTime = System.currentTimeMillis();
            logPerformance(method.getName(), endTime - startTime);
        }
        
        // 方法执行后：记录结果
        logAfter(method.getName(), result);
        
        return result;
    }
    
    private boolean checkPermission(String methodName) {
        // 模拟权限检查逻辑
        if ("admin".equals(currentUser)) {
            return true;
        }
        // 普通用户只能执行查询操作
        return methodName.startsWith("get") || methodName.startsWith("query");
    }
    
    private void logBefore(String methodName, Object[] args) {
        System.out.println("[动态代理-前置日志] 用户: " + currentUser + 
                          ", 方法: " + methodName + 
                          ", 参数: " + java.util.Arrays.toString(args) +
                          ", 时间: " + new java.util.Date());
    }
    
    private void logAfter(String methodName, Object result) {
        System.out.println("[动态代理-后置日志] 方法: " + methodName + 
                          ", 返回结果: " + result);
    }
    
    private void logException(String methodName, Exception e) {
        System.out.println("[动态代理-异常日志] 方法: " + methodName + 
                          ", 异常: " + e.getMessage());
    }
    
    private void logPerformance(String methodName, long costTime) {
        System.out.println("[动态代理-性能监控] 方法: " + methodName + 
                          ", 耗时: " + costTime + "ms");
    }
}